
const Router = require('koa-router');
const tool = require("../../tools/tool");
const router = new Router();
const {db, Op, QueryTypes} = require("../../models/db");



// 开销售单 购货单时 查询应收、付余额
router.post('/bill/strToList', async ctx => {
    try {
        let str = ctx.request.body.str
        let tenantId = ctx.user.tenantId
        let obj = strToList(str, ctx)
        if(obj.stat) {
            let list = obj.list
            if(list.length === 0) return ctx.err('没有解析到文本')
            let goods = await strToGoodList(list, ctx)
            if(goods.length === 0) return ctx.err('没有对应商品被解析')
            return ctx.suc('解析成功 ' + goods.length + ' 条', goods)
        }
        return obj
    }
    catch (e) {
        return ctx.err(e)
    }
})
const strToGoodList = async (list, ctx) => {
    let tenantId = ctx.user.tenantId
    let buId = ctx.request.body.buId
    let goods = `select a.tenantId,a.id,a.name,a.unit1,a.unit2,a.spec,a.price2,a.price1,isnull(b.buId,0) buId from v_goods a left join (select distinct tenantId,invId,buId from contact_goods where tenantId=${tenantId} and buId=${buId}) b on a.tenantId=b.tenantId and a.id=b.invId 
    where a.tenantId=${tenantId} `
    let goodList = await db.query(goods, {type: QueryTypes.SELECT})
    for (let i = 0; i < list.length; i++) {
        let row = list[i]
        let num = 20
        let idIndex = -1
        for (let j = 0; j < goodList.length; j++) {
            let good = goodList[j]
            if(good.name.includes(row.invName)) {
                num = 0
                idIndex = j
                break
            }
            else {
                let sim = tool.xe.toNumber(simlar(row.invName, good.name))
                if(sim < Math.max(row.invName.length, good.name.length)) {
                    num = sim
                    idIndex = j
                }
                if(sim === num) {
                    if(good.buId) {
                        num = sim
                        idIndex = j
                    }
                }
            }
        }
        list[i].good = num < 5 ? goodList[idIndex] : {}
    }
    let storage = await db.models['storage'].findOne({
        where: {
            tenantId,
            name: '默认仓库'
        }
    })
    if(!storage) return ctx.err('仓库设置错误')
    let glist = []
    list.map(row => {
        if(row.good.id) {
            let obj = {
                invId: row.good.id,
                invName: row.good.name,
                name: row.good.name,
                unit: row.unit === row.good.unit2 ? row.good.unit2 : row.good.unit1,
                unit1: row.good.unit1,
                unit2: row.good.unit2,
                spec: row.good.spec,
                qty: row.qty,
                locationId: storage.id,
                locationName: storage.name,
                calNum: row.unit === row.good.unit2 ? 1 : row.good.spec,
                price: row.price ? row.price : row.good.price2,
                price1: row.good.price1,
                price2: row.good.price2,
                amount: 0
            }
            obj.amount = tool.xe.toFixed(tool.xe.multiply(obj.qty, obj.price), 2)
            glist.push(obj)
        }
    })
    return glist
}

// 相似度检测
const simlar = (a, b) => {
    if (a.length === 0) return b.length;
    if (b.length === 0) return a.length;
    let matrix = [];
    // increment along the first column of each row
    let i;
    for (i = 0; i <= b.length; i++) {
        matrix[i] = [i];
    }
    // increment each column in the first row
    let j;
    for (j = 0; j <= a.length; j++) {
        matrix[0][j] = j;
    }
    // Fill in the rest of the matrix
    for (i = 1; i <= b.length; i++) {
        for (j = 1; j <= a.length; j++) {
            if (b.charAt(i-1) === a.charAt(j-1)) {
                matrix[i][j] = matrix[i-1][j-1];
            } else {
                matrix[i][j] = Math.min(matrix[i-1][j-1] + 1, // substitution
                    Math.min(matrix[i][j-1] + 1, // insertion
                        matrix[i-1][j] + 1)); // deletion
            }
        }
    }
    return matrix[b.length][a.length];
}
const numFromStr = (str) => {
    const regex = /\d+/g;
    const matches = str.match(regex);
    const numbers = matches.map(Number);
    let num = ''
    if(numbers.length > 0) {
        if(numbers.length === 0) {
            num = numbers[0]
        }
        else {
            num = numbers[0] + '.' + numbers[1]
        }
    }
    return tool.xe.toFixed(num, 2)
}
// 字符串转 数量+单位
const strToUnit = (str) => {
    const regex = /\d+/g;
    const matches = str.match(regex);
    const numbers = matches.map(Number);
    let num = ''
    if(numbers.length === 1) {
        num = numbers[0]
    }
    return [num, str.replace(num, '')]
}
const strToList = (str, ctx) => {
    let sarr = str.split('\n')
    let list = []
    for (let i = 0; i < sarr.length; i++) {
        let obj = strToGoods(tool.xe.trim(sarr[i]), ctx)
        if (!obj.stat) return obj
        if(obj) {
            list.push(obj.item)
        }
    }
    return {
        stat: true,
        list
    }
}
// 单行解析成商品
const strToGoods = (str, ctx) => {
    let arr = str.split(' ')
    let dataArr = []
    arr.map(row => {
        if(tool.xe.trim(row))
            dataArr.push(tool.xe.trim(row))
    })
    if(dataArr.length > 3) {
        return ctx.err('文本格式错误,名称 数量 单价之间要有空格,数量要带单位')
    }
    if(dataArr.length > 1) {
        let invName = tool.xe.trim(dataArr[0])
        let qty = 0
        let unit = ''
        let price = 0
        let ar = strToUnit(dataArr[1])
        if(ar.length === 1)  return ctx.err('数量由数字加单位组成')
        else if(ar.length === 2) {
            qty = tool.xe.toNumber(ar[0])
            unit = ar[1]
            if(ar[1]) {
                if(ar[1].length !== 1) return ctx.err('单位只能是1个字')
            }
        }
        else {
            return ctx.err('数量要带单位且没空格')
        }
        if(dataArr.length === 3) {
            price = numFromStr(dataArr[2])
        }
        return {
            stat: true,
            item: {
                invName,
                qty,
                unit,
                price
            }
        }
    }
    else {
        return ctx.err('格式错误')
    }
}



module.exports = router;